Python emulator

Python backend

We report here the python backend, with all the available functions, coming from the package qtealeaves

class qtealeaves.emulator.mps_simulator.MPS(num_sites, convergence_parameters, local_dim=2, initialize='vacuum', requires_singvals=False, tensor_backend=None, sectors=None, **kwargs)[source]

Matrix product states class

Parameters

num_sites: int

Number of sites

convergence_parameters: TNConvergenceParameters

Class for handling convergence parameters. In particular, in the MPS simulator we are interested in: - the maximum bond dimension \(\chi\); - the cut ratio \(\epsilon\) after which the singular

values are neglected, i.e. if \(\lamda_1\) is the bigger singular values then after an SVD we neglect all the singular values such that \(\frac{\lambda_i}{\lambda_1}\leq\epsilon\)

local_dim: int or list of ints, optional

Local dimension of the degrees of freedom. Default to 2. If a list is given, then it must have length num_sites.

initialize: str, optional

The method for the initialization. Default to “vacuum” Available: - “vacuum”, for the |000…0> state - “random”, for a random state at given bond dimension

requires_singvalsboolean, optional

Allows to enforce SVD to have singular values on each link available which might be useful for measurements, e.g., bond entropy (the alternative is traversing the whole TN again to get the bond entropy on each link with an SVD).

tensor_backendNone or instance of TensorBackend

Default for None is QteaTensor with np.complex128 on CPU.

sectorsdict, optional

Can restrict symmetry sector and/or bond dimension in initialization. If empty, no restriction. Default to None

add_site(idx, state=None)[source]

Add a site in a product state in the link idx (idx=0 is before the first site, idx=N+1 is after the last). The state of the new index is |0> or the one provided.

Parameters

idxint

index of the link where you want to add the site

state: None or array-like

Vector state that you want to add

Details

To insert a new site in the MPS we first insert an identity on a link, then add a dimension-1 link to the identity and lastly contract the new link with the initial state, usually a |0>

apply_mpo(mpo)[source]

Apply an MPO to the MPS on the sites sites. The MPO should have the following convention for the links: 0 is left link. 1 is physical link pointing downwards. 2 is phisical link pointing upwards. 3 is right link.

The sites are encoded inside the DenseMPO class.

Parameters

mpoDenseMPO

MPO to be applied

Returns

np.ndarray

Singular values cutted when the gate link is contracted

apply_nonlocal_two_site_operator(op, control, target, swap=False)[source]

Apply a non-local two-site operator, by taking first the SVD of the operator, contracting the almost-single-site operator to the respective sites and then propagating the operator to the correct site

Warning

The operations in this method are NOT ALWAYS well defined. If the left-operator tensor is not unitary, then we are applying a non-unitary operation to the state, and thus we will see a vanishing norm. Notice that, if the error can happen a warning message will be issued

Parameters

opnp.ndarray

Operator to be applied

controlint

control qubit index

targetint

target qubit index

swapbool, optional

If True, transpose the tensor legs such that the control and target are swapped. Default to False

Returns

np.ndarray

Singular values cutted when the gate link is contracted

apply_one_site_operator(op, pos)[source]

Applies a one operator op to the site pos of the MPS.

Parameters

op: QteaTensor of shape (local_dim, local_dim)

Matrix representation of the quantum gate

pos: int

Position of the qubit where to apply op.

apply_projective_operator(site, selected_output=None, remove=False)[source]

Apply a projective operator to the site site, and give the measurement as output. You can also decide to select a given output for the measurement, if the probability is non-zero. Finally, you have the possibility of removing the site after the measurement.

Warning

Applying projective measurements/removing sites is ALWAYS dangerous. The information of the projective measurement should be in principle carried over the entire mps, by iteratively applying SVDs across all sites. However, this procedure is highly suboptimal, since it is not always necessary and will be processed by the following two-sites operators. Thus, the procedure IS NOT applied here. Take care that entanglement measures through TNObsBondEntropy may give incorrect results right after a projective operator application. Furthermore, if working with parallel approaches, projective operators should be treated with even more caution, since they CANNOT be applied in parallel.

Parameters

site: int

Index of the site you want to measure

selected_output: int, optional

If provided, the selected state is measured. Throw an error if the probability of the state is 0

remove: bool, optional

If True, the measured index is traced away after the measurement. Default to False.

Returns

meas_state: int

Measured state

state_probfloat

Probability of measuring the output state

apply_two_site_operator(op, pos, swap=False, svd=True, parallel=False)[source]

Applies a two-site operator op to the site pos, pos+1 of the MPS.

Parameters

op: QteaTensor (local_dim, local_dim, local_dim, local_dim)

Matrix representation of the quantum gate

pos: int or list of ints

Position of the qubit where to apply op. If a list is passed, the two sites should be adjacent. The first index is assumed to be the control, and the second the target. The swap argument is overwritten if a list is passed.

swap: bool

If True swaps the operator. This means that instead of the first contraction in the following we get the second. It is written is a list of pos is passed.

svd: bool

If True, apply the usual contraction plus an SVD, otherwise use the QR approach explained in https://arxiv.org/pdf/2212.09782.pdf.

parallel: bool

If True, perform an approximation of the two-qubit gates faking the isometry center

Returns

singular_values_cutted: ndarray

Array of singular values cutted, normalized to the biggest singular value

Examples

swap=False  swap=True
  -P-M-       -P-M-
  2| |2       2| |2
  3| |4       4| |3
   GGG         GGG
  1| |2       2| |1
build_effective_operators(measurement_mode=False)[source]

Build the complete effective operator on each of the links. It assumes self.eff_op is set.

Parameters

measurement_modebool, optional

If True, enable measurement mode of effective operators

contract(other, boundaries=None)[source]

Contract the MPS with another MPS other <other|self>. By default it is a full contraction, but also a partial contraction is possible

Parameters

otherMPS

other MPS to contract with

boundariestuple of ints, optional

Contract to MPSs from boundaries[0] to boundaries[1]. In this case the output will be a tensor. Default to None, which is full contraction

Returns

contractioncomplex

Result of the contraction

property current_max_bond_dim

Maximum bond dimension of the mps

property default_iso_pos

Returns default isometry center position, e.g., for initialization of effective operators.

default_sweep_order(skip_exact_rgtensors=False)[source]

Default sweep order to be used in the ground state search/time evolution. Default for MPS is left-to-right.

Arguments

skip_exact_rgtensorsbool, optional

Allows to exclude tensors from the sweep which are at full bond dimension and represent just a unitary transformation. Usually set via the convergence parameters and then passed here. Default to False.

Returns

List[int]

The generator that you can sweep through

deprecated_get_eff_op_on_pos(pos)[source]

Obtain the list of effective operators adjacent to the position pos and the index where they should be contracted

Parameters

poslist

list of [layer, tensor in layer]

Returns

list of IndexedOperators

List of effective operators

list of ints

Indexes where the operators should be contracted

dot(other)[source]

Calculate the dot-product or overlap between two MPSs, i.e., <self | other>.

Parameters

otherMPS

Measure the overlap with this other MPS.

Returns ——-a

Scalar representing the overlap.

property first_non_orthogonal_left

First non orthogonal tensor starting from the left

property first_non_orthogonal_right

First non orthogonal tensor starting from the right

classmethod from_statevector(statevector, local_dim=2, conv_params=None, tensor_backend=None)[source]

Initialize the MPS tensors by decomposing a statevector into MPS form. All the degrees of freedom must have the same local dimension

Parameters

statevectorndarray of shape( local_dim^num_sites, )

Statevector describing the interested state for initializing the MPS

local_dimint, optional

Local dimension of the degrees of freedom. Default to 2.

conv_paramsTNConvergenceParameters, optional

Convergence parameters for the new MPS. If None, the maximum bond bond dimension possible is assumed, and a cut_ratio=1e-9. Default to None.

tensor_backendNone or instance of TensorBackend

Default for None is QteaTensor with np.complex128 on CPU.

Returns

objMPS

MPS simulator class

Examples

>>> -U1 - U2 - U3 - ... - UN-
>>>  |    |    |          |
# For d=2, N=7 and chi=5, the tensor network is as follows:
>>> -U1 -2- U2 -4- U3 -5- U4 -5- U5 -4- U6 -2- U7-
>>>  |      |      |      |      |      |      |
# where -x- denotes the bounds' dimension (all the "bottom-facing" indices
# are of dimension d=2). Thus, the shapes
# of the returned tensors are as follows:
>>>      U1         U2         U3         U4         U5         U6         U7
>>> [(1, 2, 2), (2, 2, 4), (4, 2, 5), (5, 2, 5), (5, 2, 4), (4, 2, 2), (2, 2, 1)]
classmethod from_tensor_list(tensor_list, conv_params=None, tensor_backend=None)[source]

Initialize the MPS tensors using a list of correctly shaped tensors

Parameters

tensor_listlist of ndarrays or cupy arrays

List of tensor for initializing the MPS

conv_paramsTNConvergenceParameters, optional

Convergence parameters for the new MPS. If None, the maximum bond bond dimension possible is assumed, and a cut_ratio=1e-9. Default to None.

tensor_backendNone or instance of TensorBackend

Default for None is QteaTensor with np.complex128 on CPU.

Returns

objMPS

The MPS class

Returns two sets of sites forming the bipartition of the system for a loopless tensor network. The link is specified via two positions in the tensor network.

Arguments

pos_srctuple of two ints

Specifies the first tensor and source of the link.

pos_dsttuple of two ints

Specifies the second tensor and destination of the link.

Returns

sites_srclist of ints

Hilbert space indices when looking from the link towards source tensor and following the links therein.

sites_dstlist of ints

Hilbert space indices when looking from the link towards destination tensor and following the links therein.

List of tensor position where links are leading to.

Parameters

posint

Index of the tensor in the MPS

Returns

Tuple[int]

Index of the tensor connected through links to pos. None if they are open links.

Get the position of the partner tensor to use in the link expansion subroutine. It is the tensor towards the center, that is supposed to be more entangled w.r.t. the tensor towards the edge

Parameters

posint

Position w.r.t. which you want to compute the partner

Returns

int

Position of the partner

int

Link of pos pointing towards the partner

int

Link of the partner pointing towards pos

get_rho_i(idx)[source]

Get the reduced density matrix of the site at index idx

Parameters

idxint

Index of the site

Returns

_AbstractQteaTensor

Reduced density matrix of the site

get_tensor_of_site(idx)[source]

Generic function to retrieve the tensor for a specific site. Compatible across different tensor network geometries. This function does not shift the gauge center before returning the tensor.

Parameters

idxint

Return tensor containing the link of the local Hilbert space of the idx-th site.

property iso_center

Output the gauge center if it is well defined, otherwise None

iso_towards(new_iso, keep_singvals=False, trunc=False, conv_params=None, move_to_memory_device=True, normalize=False)[source]

Apply the gauge transformation to shift the isometry center to a specific site new_iso. The method might be different for other TN structure, but for the MPS it is the same.

Parameters

new_isoint

Position in the TN of the tensor which should be isometrized.

keep_singvalsbool, optional

If True, keep the singular values even if shifting the iso with a QR decomposition. Default to False.

truncBoolean, optional

If True, the shifting is done via truncated SVD. If False, the shifting is done via QR. Default to False.

conv_paramsTNConvergenceParameters, optional

Convergence parameters to use for the SVD. If None, convergence parameters are taken from the TTN. Default to None.

move_to_memory_devicebool, optional

If True, when a mixed device is used, move the tensors that are not the isometry center back to the memory device. Default to True.

normalizebool, optional

Flag if intermediate steps should normalize. Default to False

Details

The tensors used in the computation will always be moved on the computational device. For example, the isometry movement keeps the isometry center end the effective operators around the center (if present) always on the computational device. If move_to_memory_device is False, then all the tensors (effective operators) on the path from the old iso to the new iso will be kept in the computational device. This is very useful when you iterate some protocol between two tensors, or in general when two tensors are involved.

kron(other, inplace=False)[source]

Concatenate two MPS, taking the kronecker/outer product of the two states. The bond dimension assumed is the maximum between the two bond dimensions.

Parameters

otherMPS

MPS to concatenate

inplacebool, optional

If True apply the kronecker product in place. Instead, if inplace=False give as output the product. Default to False.

Returns

MPS

Concatenation of the first MPS with the second in order

left_canonize(idx, trunc=False, keep_singvals=False, conv_params=None, move_to_memory_device=True, normalize=False)[source]

Apply a gauge transformation to all bonds between 0 and idx, so that all sites between the first (òeftmpst one) and idx are set to (semi)-unitary tensors.

Parameters

idx: int

index of the tensor up to which the canonization occurs

trunc: bool, optional

If True, use the SVD instead of the QR for the canonization. It might be useful to reduce the bond dimension. Default to False.

keep_singvalsbool, optional

If True, keep the singular values even if shifting the iso with a QR decomposition. Default to False.

conv_paramsTNConvergenceParameters, optional

Convergence parameters to use for the SVD in the procedure. If None, convergence parameters are taken from the TTN. Default to None.

move_to_memory_devicebool, optional

If True, when a mixed device is used, move the tensors that are not the isometry center back to the memory device. Default to True.

normalizebool, optional

Flag if singular values should be normalized. Default to False

meas_bond_entropy()[source]

Measure the entanglement entropy along all the sites of the MPS using the Von Neumann entropy \(S_V\) defined as:

\[S_V = - \sum_i^{\chi} s^2 \ln( s^2)\]

with \(s\) the singular values

Return

measuresdict

Keys are the range of the bipartition from 0 to which the entanglement (value) is relative

meas_even_probabilities(threshold, qiskit_convention=False)[source]

Compute the probabilities of measuring a given state if it is greater than a threshold. The function goes down “evenly” on the probability tree. This means that there is the possibility that no state is returned, if their probability is lower then threshold. Furthermore, notice that the maximum number of states returned is :math:`(

rac{1}{threshold})`.

For a different way of computing the probability tree see the function meas_greedy_probabilities() or meas_unbiased_probabilities().

thresholdfloat

Discard all the probabilities lower then the threshold

qiskit_conventionbool, optional

If the sites during the measure are represented such that |201> has site 0 with value one (True, mimicks bits ordering) or with value 2 (False usually used in theoretical computations). Default to False.

probabilitiesdict

Dictionary where the keys are the states while the values their probabilities. The keys are separated by a comma if local_dim > 9.

meas_greedy_probabilities(max_prob, max_iter=None, qiskit_convention=False)[source]

Compute the probabilities of measuring a given state until the total probability measured is greater than the threshold max_prob. The function goes down “greedily” on the probability tree. This means that there is the possibility that a path that was most promising at the tree root will become very computationally demanding and not so informative once reached the leaves. Furthermore, notice that there is no maximum number of states returned, and so the function might be exponentially slow.

For a different way of computing the probability tree see the function meas_even_probabilities() or meas_unbiased_probabilities()

Parameters

max_probfloat

Compute states until you reach this probability

qiskit_conventionbool, optional

If the sites during the measure are represented such that |201> has site 0 with value one (True, mimicks bits ordering) or with value 2 (False usually used in theoretical computations). Default to False.

Return

probabilitiesdict

Dictionary where the keys are the states while the values their probabilities. The keys are separated by a comma if local_dim > 9.

meas_tensor_product(ops, idxs)[source]

Measure the tensor products of n operators ops acting on the indexes idxs. The operators should be MPOs, i.e. rank-4 tensors of shape (left, up, down, right). To retrieve the tensor product operators, left=right=1.

Parameters

opslist of ndarrays

List of numpy arrays which are one-site operators

idxslist of int

Indexes where the operators are applied

Returns

measurefloat

Result of the measurement

meas_weighted_sum(op_strings, idxs_strings, coefs)[source]

Measure the weighted sum of tensor product operators. See meas_tensor_product()

Parameters

op_stringslist of lists of ndarray

list of tensor product operators

idxs_stringslist of list of int

list of indexes of tensor product operators

coefslist of complex

list of the coefficients of the sum

Return

measurecomplex

Result of the measurement

ml_get_gradient_tensor(idx, data_sample, true_label)[source]

Get the gradient w.r.t. the tensors at position idx, idx+1 of the MPS following the procedure explained in https://arxiv.org/pdf/1605.05775.pdf for the data_sample given

Parameters

idxint

Index of the tensor to optimize

data_samplepy:class:MPS

Data sample in MPS class

true_labelint

True label of the datasample

Returns

xp.ndarray

Gradient tensor

ml_optimize_mps(data_samples, true_labels, batch_size, learning_rate, num_sweeps, n_jobs=1)[source]

Optimize the MPS using the algorithm of Stoudenmire

Parameters

data_samplesList[py:class:MPS]

Feature dataset

true_labelsList[int]

Labels of the dataset

batch_sizeint

Number of samples for a single sweep(epoch)

learning_ratefloat or callable

Learning rate for the tensor update. If callable, it can depend on the sweep.

num_sweepsint

Number of optimization sweeps (epochs)

n_jobsint, optional

Number of parallel jobs for the optimization, by default 1

Returns

xp.ndarray

Singular values cut in the optimization

xp.ndarray

Value of the loss function at each sweep(epoch)

ml_optmize_tensor(idx, data_samples, true_labels, learning_rate, n_jobs=1, direction=1)[source]

Optimize a single tensor using a batch of data damples

Parameters

idxint

Index of the tensor to optimize

data_samplesList[py:class:MPS]

List of data samples

true_labelsxp.ndarray

List of labels (0 or 1)

learning_ratefloat

Learining rate for the tensor update

n_jobsint, optional

Number of parallel jobs for the optimization, by default 1

Returns

xp.ndarray

Singular values cut in the optimization

float

Value of the loss function

ml_predict(data_samples, n_jobs=1)[source]

Predict the labels of the data samples passed

Parameters

data_samplesList[py:class:MPS]

Feature dataset

true_labelsList[int]

Labels of the dataset

n_jobsint, optional

Number of parallel jobs for the optimization, by default 1

Returns

List

Predicted labels

modify_local_dim(value, idxs=None)[source]

Modify the local dimension of sites idxs to the value value. By default modify the local dimension of all the sites. If value is a vector then it must have the same length of idxs. Notice that there may be loss of information, it is up to the user to be sure no error is done in this procedure.

Parameters

valueint or array-like

New value of the local dimension. If an int, it is assumed it will be the same for all sites idxs, otherwise its length must be the same of idxs.

idxsint or array-like, optional

Indexes of the sites to modify. If None, all the sites are modified. Default to None.

classmethod mpi_bcast(state, comm, tensor_backend, root=0)[source]

Broadcast a whole tensor network.

Arguments

stateMPS (for MPI-rank root, otherwise None is acceptable)

State to be broadcasted via MPI.

commMPI communicator

Send state to this group of MPI processes.

tensor_backendTensorBackend

Needed to identity data types and tensor classes on receiving MPI threads (plus checks on sending MPI thread).

rootint, optional

MPI-rank of sending thread with the state. Default to 0.

static mpi_sample_n_unique_states(state, num_unique, comm, tensor_backend, cache_size=None, cache_clearing_strategy=None, filter_func=None, mpi_final_op=None, root=0, **kwargs)[source]

Try sampling a target number of unique states from TN ansatz.

mps_multiply_mps(other)[source]

Elementwise multiplication of the MPS with another MPS, resulting multiplying the coefficients of the statevector representation. If self represents the state a|000>+b|111> and other represent c|000>+d|111> then self.mps_multiply_mps(other)=ac|000>+bd|111>. It is very computationally demanding and the new bond dimension is the product of the two original bond dimensions.

Parameters

otherMPS

MPS to multiply

Returns

MPS

Summation of the first MPS with the second

norm()[source]

Returns the norm of the MPS as sqrt(<self|self>)

Return

norm: float

norm of the MPS

normalize()[source]

Normalize the MPS state, by dividing by \(\sqrt{<\psi|\psi>}\).

property physical_idxs

Physical indices property

classmethod read(filename, tensor_backend, cmplx=True, order='F')[source]

Read an MPS written by FORTRAN in a formatted way on file. Reads in column-major order but the output is in row-major. This is the only method that overrides the number of sites, since you may not know before reading.

Parameters

filename: str

PATH to the file

tensor_backendTensorBackend

Setup which tensor class to create.

cmplx: bool, optional

If True the MPS is complex, real otherwise. Default to True

order: str, optional

If ‘F’ the tensor is transformed from column-major to row-major, if ‘C’ it is left as read.

Returns

obj: py:class:MPS

MPS class read from file

reset(idxs=None)[source]

Reset the states of the sites idxs to the |0> state

Parameters

idxsint or list of ints, optional

indexes of the sites to reinitialize to 0. If default value is left all the sites are restarted.

right_canonize(idx, trunc=False, keep_singvals=False, conv_params=None, move_to_memory_device=True, normalize=False)[source]

Apply a gauge transformation to all bonds between :py:method:`MPS.num_sites` and idx, so that all sites between the last (rightmost one) and idx are set to (semi)-unitary tensors.

Parameters

idx: int

index of the tensor up to which the canonization occurs

trunc: bool, optional

If True, use the SVD instead of the QR for the canonization. It might be useful to reduce the bond dimension. Default to False.

keep_singvalsbool, optional

If True, keep the singular values even if shifting the iso with a QR decomposition. Default to False.

conv_paramsTNConvergenceParameters, optional

Convergence parameters to use for the SVD in the procedure. If None, convergence parameters are taken from the TTN. Default to None.

move_to_memory_devicebool, optional

If True, when a mixed device is used, move the tensors that are not the isometry center back to the memory device. Default to True.

normalizebool, optional

Flag if intermediate steps should normalize. Default to False

scale(factor)[source]

Scale the MPS state by a scalar constant using the gauge center.

Parameters

factorscalar

Factor is multiplied to the MPS at the gauge center.

Update or set singvals on link via two positions.

property singvals

List of singular values in the bonds

site_canonize(idx, keep_singvals=False, normalize=False)[source]

Apply the gauge transformation to shift the isometry center to a specific site idx.

Parameters

idx: int

index of the tensor up to which the canonization occurs from the left and right side.

keep_singvalsbool, optional

If True, keep the singular values even if shifting the iso with a QR decomposition. Default to False.

normalizebool, optional

Flag if intermediate steps should normalize. Default to False

swap_qubits(sites, conv_params=None, trunc=True)[source]

This function applies a swap gate to sites in an MPS, i.e. swaps these two qubits

Parameters

sitesTuple[int]

The qubits on site sites[0] and sites[1] are swapped

conv_paramsTNConvergenceParameters, optional

Convergence parameters to use for the SVD in the procedure. If None, convergence parameters are taken from the TTN. Default to None.

Return

np.ndarray

Singualr values cut in the process of shifting the isometry center. None if moved through the QR.

property tensors

List of MPS tensors

to_dense(true_copy=False)[source]

Return MPS without symmetric tensors.

Parameters

true_copybool, optional

The function can be forced to return an actual copy with true_copy=True, while otherwise self can be returned if the MPS is already without symmetries. Default to False

Returns

dense_mpsMPS

MPS representation without symmetric tensors.

to_statevector(qiskit_order=False, max_qubit_equivalent=20)[source]

Given a list of N tensors MPS [U1, U2, …, UN] , representing a Matrix Product State, perform the contraction in the Examples, leading to a single tensor of order N, representing a dense state.

The index ordering convention is from left-to-right. For instance, the “left” index of U2 is the first, the “bottom” one is the second, and the “right” one is the third.

Parameters

qiskit_order: bool, optional

weather to use qiskit ordering or the theoretical one. For example the state |011> has 0 in the first position for the theoretical ordering, while for qiskit ordering it is on the last position.

max_qubit_equivalent: int, optional

Maximum number of qubit sites the MPS can have and still be transformed into a statevector. If the number of sites is greater, it will throw an exception. Default to 20.

Returns

psindarray of shape (d ^ N, )

N-order tensor representing the dense state.

Examples

>>> U1 - U2 - ... - UN
>>>  |    |          |
to_tensor_list()[source]

Return the tensor list representation of the MPS. Required for compatibility with TTN emulator

Return

list

List of tensors of the MPS

to_ttn()[source]

Return a tree tensor network (TTN) representation as binary tree.

Details

The TTN is returned as a listed list where the tree layer with the local Hilbert space is the first list entry and the uppermost layer in the TTN is the last list entry. The first list will have num_sites / 2 entries. The uppermost list has two entries.

The order of the legs is always left-child, right-child, parent with the exception of the left top tensor. The left top tensor has an additional link, i.e., the symmetry selector; the order is left-child, right-child, parent, symmetry-selector.

Also see :py:func:ttn_simulator:`from_tensor_list`.

write(filename, cmplx=True)[source]

Write an MPS in python format into a FORTRAN format, i.e. transforms row-major into column-major

Parameters

filename: str

PATH to the file

cmplx: bool, optional

If True the MPS is complex, real otherwise. Default to True

Returns

None